package edu.dhbw.andar.sample;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.RejectedExecutionException;

import org.cocos2d.layers.CCColorLayer;
import org.cocos2d.layers.CCLayer;
import org.cocos2d.layers.CCScene;
import org.cocos2d.nodes.CCDirector;
import org.cocos2d.types.CGPoint;
import org.cocos2d.types.CGRect;
import org.cocos2d.types.CGSize;
import org.cocos2d.types.ccColor4B;

import android.view.MotionEvent;

/**Game layer handles UI, content and game loop*/
public class GameLayer extends CCColorLayer {
	//Fields
	private NFCFeedback _dPad;
	private ActionSlots _actions;
	public static GameLayer scene;
	private CustomActivity arManager;
	
	private Arbject currentArbject;
	
	/**Constructor sets up game components*/
	protected GameLayer(ccColor4B color){
	    super(color);
	    CGSize winSize = CCDirector.sharedDirector().displaySize();
	    //Add d-pad graphics
	    _dPad = new NFCFeedback("d-pad.png", 98, 98);
	    addChild(_dPad.getSprite());
	    float x = winSize.width - 115 * 2 - 10 ;
	    float y = 98 * 2 + 10;
	    _actions = new ActionSlots("activeSlot.png", x, y);
	    _actions.getNode().setScale(2.0f);
	    addChild(_actions.getNode());
	    
	    //Schedule update and enable touch
	    this.schedule("update");
	    this.schedule("serverUpdate", 0.5f);
	    this.setIsTouchEnabled(true);
	    
	    currentArbject = null;
	    
//	    Context context = CCDirector.sharedDirector().getActivity();
//	    SoundEngine.sharedEngine().preloadEffect(context, R.raw.pew_pew_lei);
//	    SoundEngine.sharedEngine().playSound(context, R.raw.background_music_aac, true);
	}
	
	/**Main game loop */
	public void update(float dt) {
	    //Update GUI
	    _dPad.update(dt);
	    _actions.update(dt);
	}

	/**Server loop
	 * @throws ExecutionException 
	 * @throws InterruptedException */
	public void serverUpdate(float dt){
		new Thread(){
			public void run(){
				String card;
				try {
					
					for(String arbjectKey : arManager.getArbjects().keySet()){
						card = getSharedData(arbjectKey);
						
						if(!card.equals(arManager.getArbject(arbjectKey).getValue())){
							arManager.changeModel(arbjectKey, card);
						}
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				} catch (RejectedExecutionException e) {
					e.printStackTrace();
				} catch (RuntimeException e) {
					e.printStackTrace();
				}
				
				this.interrupt();
				}
		}.start();
	}
	
	/**
	 * Sets a shared variable on the server to a specified value.
	 * This variable will then be accessed by all clients
	 * for synchronization.
	 * @param key The variable to be set.
	 * @param value The value to set the variable to.
	 */
    public void setSharedData(String key, String value){
    	new Client().execute(key + ":" + value);
    }
    
    /**
     * Get the value for a shared variable on the server.
     * @param key The variable that you want the value for.
     * @return The value for the parameter {@code key}, represented as a {@link java.lang.String}.
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public String getSharedData(String key) throws InterruptedException, ExecutionException{
    	return new Client().execute(key).get();
    }
	
	/**
	 * @Override
	 * Implementation of touches began event
	 */
	public boolean ccTouchesBegan(MotionEvent event){
		//
		CGPoint touchPoint = CCDirector.sharedDirector().convertToGL(
						CGPoint.ccp(event.getX(), event.getY()));
		CGRect fingerRect = CGRect.make(touchPoint.x - 22, touchPoint.y - 22, 44, 44);
		int touchID = event.getPointerId(event.getActionIndex());
		//
		if(_dPad.isIntersecting(fingerRect)){
			_dPad.setTouchID(touchID);
		} else if(_actions.isIntersecting(fingerRect)){
			_actions.startTouch(touchID, touchPoint);
		}
		return true;
	}
	
	
	/**
	 * @Override
	 * Implementation of touches moved event
	 */
	public boolean ccTouchesMoved(MotionEvent event) {
		boolean touchingDPad = false;
		//Iterate through all touches
		for(int i = 0; i < event.getPointerCount(); i++){
			CGPoint touchPoint = CCDirector.sharedDirector().convertToGL(
					CGPoint.ccp(event.getX(i), event.getY(i)));
			CGRect fingerRect = CGRect.make(touchPoint.x - 22, touchPoint.y - 22, 44, 44);
			int touchID = event.getPointerId(i);
			//A touch is intersecting with the d-pad, so update d-pads touch ID
			if(_dPad.isIntersecting(fingerRect)){
				if(_dPad.hasTouchID(touchID)){
				} else {
					_dPad.setTouchID(touchID);
				}
				touchingDPad = true;
			}
			//A touch is intersecting with the actions, so update actions touch ID
			else if(_actions.isIntersecting(fingerRect)){
				if(_actions.hasTouchID(touchID)){
					_actions.updateTouch(touchPoint);
					performHoldAction();
				} else {
					_actions.startTouch(touchID, touchPoint);
				}
			}
		}
		if(!touchingDPad){
			_dPad.setTouchID(-1);
		}
		return true;
    }
	
	/**
	 * @Override
	 * Implementation of touches ended event
	 */
	public boolean ccTouchesEnded(MotionEvent event){
		int touchID = event.getPointerId(event.getActionIndex());
		//Touch which ended had ID of the d-pad
		if(_dPad.hasTouchID(touchID)){
			_dPad.setTouchID(-1);
		}
		//Touch which ended had the ID of the actions
		else if(_actions.hasTouchID(touchID)){
			if(_actions.wasSwiped()){
				_actions.swapActions();
			}
			//
			else{
				performTapAction();
			}
			_actions.resetTouch();
		}
	    return true;
	}
	
	/**Actions to be performed when the action slots were tapped*/
	private void performTapAction(){
		if(currentArbject != null){
			//TODO: testing tap actions for a specific item
			if(_actions.getCurrentAction() == "superman"){
				arManager.changeModel(currentArbject.getID(), "superman");
				setSharedData(currentArbject.getID(), "superman");
			} else if(_actions.getCurrentAction() == "bench"){
				arManager.changeModel(currentArbject.getID(), "bench");
				setSharedData(currentArbject.getID(), "bench");
			} else if(_actions.getCurrentAction() == "sofa"){
				arManager.changeModel(currentArbject.getID(), "sofa");
				setSharedData(currentArbject.getID(), "sofa");
			}
			
			_dPad.setImage("none");
			_actions.setVisible(false);
			
			currentArbject.isVisible = true;
			currentArbject = null;
		}
	}
	
	/**Actions to be performed when the action slots are tapped and held */
	private void performHoldAction(){
		//TODO: testing hold action for a specific item
		if(_actions.getCurrentAction() == "knife"){
		}
	}
	
	public void receiveNFC(String id){
//		Log.d("TAG", id);
		currentArbject = arManager.getArbject(id);
		_dPad.setImage(currentArbject.getName());
		_actions.setVisible(true);
	}
	
	public void setARManager(CustomActivity arManager){
		this.arManager = arManager;
	}
	
	/**Implementation of objective-c like allocation for this object*/
	public static CCScene scene(){
	    CCScene scene = CCScene.node();
	    CCLayer layer = new GameLayer(new ccColor4B(0, 0, 255, 0));
	 
	    scene.addChild(layer);
	 
	    return scene;
	}
}
